package com.program.facesigninsystem.controller;

import cn.yueshutong.springbootstartercurrentlimiting.annotation.CurrentLimiter;
import com.arcsoft.face.FaceFeature;
import com.arcsoft.face.FaceInfo;
import com.auth0.jwt.JWT;
import com.program.facesigninsystem.entity.*;
import com.program.facesigninsystem.face.ArcSoftFace;
import com.program.facesigninsystem.service.*;
import com.program.facesigninsystem.service.impl.RedisServiceImpl;
import com.program.facesigninsystem.service.impl.ScanCodeLoginService;
import com.program.facesigninsystem.util.*;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.*;



/**
 * @author Mapler
 */
@CrossOrigin
@RestController
@RequestMapping(value = "/auth")
public class UserController {
    private final static Logger logger = LoggerFactory.getLogger(UserController.class);
    final private String TEMPORARY_FILE_PATH2 = "C:\\tmp\\";

    private IUserInfoService iUserInfoService;
    private IRewardService iRewardService;
    private IClassesService iClassesService;
    private IUserClassService iUserClassService;
    private ISignInRecordService iSignInRecordService;
    private ISignInActivityService iSignInActivityService;
    private ScanCodeLoginService iScanCodeLoginService;
    private RedisServiceImpl redisService;

    @Autowired
    public UserController(IUserInfoService iUserInfoService, IRewardService iRewardService, IClassesService iClassesService, IUserClassService iUserClassService, ISignInRecordService iSignInRecordService, ISignInActivityService iSignInActivityService, ScanCodeLoginService iScanCodeLoginService,RedisServiceImpl redisService) {
        this.iUserInfoService = iUserInfoService;
        this.iRewardService = iRewardService;
        this.iClassesService = iClassesService;
        this.iUserClassService = iUserClassService;
        this.iSignInRecordService = iSignInRecordService;
        this.iSignInActivityService = iSignInActivityService;
        this.iScanCodeLoginService = iScanCodeLoginService;
        this.redisService = redisService;
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @CurrentLimiter(QPS = 5)
    public ResponseModel loginUser(HttpServletRequest request, @RequestBody JSONObject account) throws Exception {
        ResponseModel responseModel;
        String openid;
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            String appId = "wx8b04000a8e310474";
            String secret = "e79a1ce78b98e5addd495f3e6970920e";
            openid = HttpClient.getWxUserOpenid(account.get("code").toString(), appId, secret).get("openid").toString();
        } catch (Exception e) {
            responseModel = new ResponseModel(199, "微信授权失败");
            return responseModel;
        }
        UserInfo userInfo = iUserInfoService.loginUser(openid);
        if (userInfo != null) {
            //判断该用户token是否为空
            if (userInfo.getToken() == null || "".equals(userInfo.getToken())) {
                String token = TokenUtil.createToken(userInfo.getUid(), userInfo.getOpenid(), 1000 * 60L);
                userInfo.setToken(token);
                //token存入用户数据库
                iUserInfoService.updateToken(userInfo.getUid(), token);
            } else {
                if (!TokenUtil.decodeToken(userInfo.getToken())) {
                    String token = TokenUtil.createToken(userInfo.getUid(), userInfo.getOpenid());
                    userInfo.setToken(token);
                    //token存入用户数据库
                    iUserInfoService.updateToken(userInfo.getUid(), token);
                }
            }
            String userAvatar = account.getString("userAvatar");
            String userAlias = account.getString("userAlias");
            iUserInfoService.updateAvatar(userInfo.getUid(), userAvatar,userAlias);
            userInfo = iUserInfoService.loginUser(openid);
            if (userAvatar == null) {
                responseModel = new ResponseModel(138, "登录失败，未传头像");
            } else {
                User user=redisService.findByUId(userInfo.getUid());
                //保存登陆信息
                String currentTime = dateFormat.format(System.currentTimeMillis());
                String ip=GetInfoUtil.getIpAddr(request);
                if(user==null){
                    redisService.addUser(userInfo.getUid(),ip,currentTime,"0");
                }else {
                    redisService.updateByUId(userInfo.getUid(),ip,currentTime);
                }
                logger.info("登陆信息 uid:"+userInfo.getUid1()+",ip:"+ip);
                responseModel = new ResponseModel(200, "登录成功", userInfo);
            }
        } else {
            String uid = GetInfoUtil.getId();
            String uid1 = "wx" + GetInfoUtil.getId(8);
            userInfo = new UserInfo();
            String token = TokenUtil.createToken(uid, openid);
            userInfo.setToken(token);
            userInfo.setUid(uid);
            userInfo.setOpenid(openid);
            userInfo.setUid1(uid1);
            iUserInfoService.addUser(uid, openid, token, account.getString("userAvatar"),account.getString("userAlias"), uid1);

            //保存登陆信息
            String currentTime = dateFormat.format(System.currentTimeMillis());
            String ip=GetInfoUtil.getIpAddr(request);
            redisService.addUser(uid,ip,currentTime,"0");
            logger.info("登陆信息 uid:"+uid+",ip:"+ip);

            userInfo=redisService.findUser(uid);
            if (userInfo==null){
                userInfo = iUserInfoService.loginUser(openid);
                redisService.addUserInfo(userInfo,userInfo.getClass().toString());
            }

            responseModel = new ResponseModel(200, "登录成功", userInfo);
        }
        return responseModel;
    }

    @RequestMapping(value = "/active", method = RequestMethod.GET)
    public ResponseModel active() {
        ResponseModel responseModel;

        ArcSoftFace arcSoftFace = new ArcSoftFace();
        int errorCode = arcSoftFace.activeOnline();
        int alreadyActivated = 90114;
        if (errorCode == 0) {
            responseModel = new ResponseModel(200, "激活成功", errorCode);
        } else if (errorCode == alreadyActivated) {
            responseModel = new ResponseModel(181, "已激活，请勿重复激活", errorCode);
        } else {
            responseModel = new ResponseModel(189, "激活失败", errorCode);
        }
        return responseModel;
    }

    @RequestMapping(value = "/userTypeAlter", method = RequestMethod.GET)
    public ResponseModel updateUserType(@RequestParam("uid") String uid, @RequestParam("type") int type) {
        try {
            iUserInfoService.updateUserType(uid, type);
            int student = 2;
            if (type == student) {
                if (iUserInfoService.selectFaceFeature(uid) != null) {
                    return new ResponseModel(200, "切换成功", "Registered");
                } else {
                    return new ResponseModel(200, "切换成功", "NotRegister");
                }
            } else {
                return new ResponseModel(200, "切换成功");
            }
        } catch (Exception e) {
            return new ResponseModel(125, "切换失败");
        }
    }

    @RequestMapping(value = "/adminLogin", method = RequestMethod.POST)
    public ResponseModel adminLogin(@RequestBody JSONObject jsonObject) {
        ResponseModel responseModel;
        String password;
        try {
            password = jsonObject.get("password").toString();
        } catch (Exception e) {
            password = "";
        }
        String[] strs=EncryptionUtil.md5Encrypt("opyhjp",password);
        Object object = iUserInfoService.selectAdmin(jsonObject.getString("user"), strs[1]);
        if (object != null) {
            String token = TokenUtil.createToken(jsonObject.getString("user"), "op82Q4iUHjAXTpRulfRXhKbYYLKE");
            iUserInfoService.adminToken(jsonObject.getString("user"), token);
            responseModel = new ResponseModel(200, "登录成功", token);
        } else {
            responseModel = new ResponseModel(132, "用户名或密码错误");
        }
        return responseModel;
    }

    @RequestMapping(value = "/addFace", method = RequestMethod.POST)
    @CurrentLimiter(QPS = 5)
    public ResponseModel addFace(@RequestParam("uid") String uid, @RequestParam("file") MultipartFile multipartFile) {
        ArcSoftFace arcSoftFace = new ArcSoftFace();
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String createTime = simpleDateFormat.format(System.currentTimeMillis());
            File file = new File(TEMPORARY_FILE_PATH2+GetInfoUtil.getFileName());
            multipartFile.transferTo(file);
            List<FaceInfo> faceInfoList = arcSoftFace.detectFaces(file);
            if (arcSoftFace.getLiveness() != 1) {
                arcSoftFace.destroyEngine();
                return new ResponseModel(184, "活体检测不成功");
            }
            FaceFeature faceFeature = new FaceFeature(arcSoftFace.extractFaceFeature(file, faceInfoList));
            if (faceFeature.getFeatureData() == null) {
                arcSoftFace.destroyEngine();
                return new ResponseModel(188, "添加人脸失败，未检测到人脸");
            }
            iUserInfoService.addFace(uid, faceFeature.getFeatureData(),createTime);
            arcSoftFace.destroyEngine();
            return new ResponseModel(200, "添加人脸成功");
        } catch (Exception e) {
            logger.error(String.valueOf(e));
            arcSoftFace.destroyEngine();
            return new ResponseModel(188, "添加人脸失败，未检测到人脸");
        }
    }


    @RequestMapping(value = "/compareFace", method = RequestMethod.POST)
    @CurrentLimiter(QPS = 10)
    public ResponseModel compareFaceFeature(@RequestParam("uid") String uid, @RequestParam("file") MultipartFile multipartFile) {
        ArcSoftFace arcSoftFace = new ArcSoftFace();
        try {
            byte[] bytes = iUserInfoService.selectFaceFeature(uid);
            if (bytes == null) {
                return new ResponseModel(185, "没有此用户的人脸信息");
            }

            File file = new File(TEMPORARY_FILE_PATH2+GetInfoUtil.getFileName());
            multipartFile.transferTo(file);
            FaceFeature targetFaceFeature = new FaceFeature(bytes);
            List<FaceInfo> faceInfoList = arcSoftFace.detectFaces(file);
            if (arcSoftFace.getLiveness() != 1) {
                arcSoftFace.destroyEngine();
                return new ResponseModel(183, "活体检测不成功");
            }
            byte[] bytes1 = arcSoftFace.extractFaceFeature(file, faceInfoList);
            if (bytes1 == null) {
                arcSoftFace.destroyEngine();
                return new ResponseModel(186, "上传的图片没有识别到人脸信息");
            }
            FaceFeature sourceFaceFeature = new FaceFeature(bytes1);
            float result = arcSoftFace.compareFaceFeature(targetFaceFeature, sourceFaceFeature);
            arcSoftFace.destroyEngine();
            return new ResponseModel(200, "对比成功", result);
        } catch (Exception e) {
            logger.error(String.valueOf(e));
            arcSoftFace.destroyEngine();
            return new ResponseModel(187, "对比失败");
        }
    }

    @SuppressWarnings("unchecked")
    @RequestMapping(value = "/updateUserById", method = RequestMethod.POST)
    public ResponseModel updateUserById(@RequestBody JSONObject data) {
        try {
            int type, age;
            String uid = data.get("uid").toString();
            String name, major, uclass, university, academy, avatar, sex, address, phone, email;
            name = data.getOrDefault("name", "").toString();
            type = Integer.parseInt(data.getOrDefault("type", 100).toString());
            age = Integer.parseInt(data.getOrDefault("age", -1).toString());
            major = data.getOrDefault("major", "").toString();
            uclass = data.getOrDefault("uclass", "").toString();
            university = data.getOrDefault("university", "").toString();
            academy = data.getOrDefault("academy", "").toString();
            avatar = data.getOrDefault("avatar", "").toString();
            sex = data.getOrDefault("sex", "").toString();
            address = data.getOrDefault("address", "").toString();
            phone = data.getOrDefault("phone", "").toString();
            email = data.getOrDefault("email", "").toString();
            //当无更新参数type，type默认值100
            try {
                redisService.updateUser(uid, name, type, major, uclass, university, academy, avatar, sex, age, address, phone, email);
                iUserInfoService.updateUser(uid, name, type, major, uclass, university, academy, avatar, sex, age, address, phone, email);
                return new ResponseModel(200, "更新成功");
            } catch (Exception e) {
                return new ResponseModel(199, "更新失败");
            }
        } catch (Exception e) {
            return new ResponseModel(198, "请先注册");
        }
    }

    @RequestMapping(value = "/dailyTask", method = RequestMethod.GET)
    public ResponseModel dailyTask(@RequestParam("uid") String uid) {
        try {
            Rewards rewards = iRewardService.selectReward(uid);
            String task1 = "创建签到1次";
            int maxRewardTimes = 3;
            int rewardPerTime = 30;
            int dayRewardMax = 100;
            int rewardPerTimeForTeacher = 2;
            String task11 = "0/" + rewardPerTime + "积分";
            String task2 = "参与签到3次";
            int task21 = 0;
            String task22 = "/" + rewardPerTime * 3 + " 积分";
            String task3 = "他人参加你的签到共获得 ";
            int task31 = 0;
            String task32 = " 积分(" + rewardPerTimeForTeacher + "积分/次）";
            String task1button = "去完成";
            String task2button = "去完成";
            Map<String, Object> map = new HashMap<>(12);
            map.put("task1", task1);
            map.put("task2", task2);
            map.put("task11", task11);
            map.put("task22", task21 + task22);
            map.put("task1button", task1button);
            map.put("task2button", task2button);
            map.put("task3", task3 + task31 + task32);
            map.put("task4", "今日可获得积分上限");
            map.put("task41", 0);
            map.put("task42", dayRewardMax);
            map.put("task1pointsPerTime", "+" + rewardPerTime);
            map.put("task2pointsPerTime", "+" + rewardPerTime);
            if (rewards == null) {
                return new ResponseModel(200, "获取成功", map);
            }
            SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String currentDay = dateformat.format(System.currentTimeMillis()).substring(0, 10);
            if (!rewards.getLast_gain_day().equals(currentDay)) {
                return new ResponseModel(200, "获取成功", map);
            } else {
                int todayReward = rewards.getDay_reward();
                if (rewards.getLimit_from_activity() == 1) {
                    task11 = rewardPerTime + "/" + rewardPerTime + " 积分";
                    task1button = "已完成";
                    todayReward -= rewardPerTime;
                }
                if (rewards.getLimit_from_record_a() == 1) {
                    task21 += rewardPerTime;
                    todayReward -= rewardPerTime;
                }
                if (rewards.getLimit_from_record_b() == 1) {
                    task21 += rewardPerTime;
                    todayReward -= rewardPerTime;
                }
                if (rewards.getLimit_from_record_c() == 1) {
                    task21 += rewardPerTime;
                    todayReward -= rewardPerTime;
                }
                if (task21 == rewardPerTime * maxRewardTimes) {
                    task2button = "已完成";
                }
                map.put("task11", task11);
                map.put("task22", task21 + task22);
                map.put("task1button", task1button);
                map.put("task2button", task2button);
                map.put("task3", task3 + todayReward + task32);
                map.put("task41", rewards.getDay_reward());
                return new ResponseModel(200, "获取成功", map);
            }
        } catch (Exception e) {
            return new ResponseModel(150, "获取失败");
        }
    }

    @RequestMapping(value = "/selectUserById", method = RequestMethod.POST)
    public ResponseModel selectUserById(@RequestBody JSONObject data) {
        String uid = data.get("uid").toString();
        //返回用户信息
        Map<String, Object> userInfo = iUserInfoService.selectUser(uid);
        ResponseModel responseModel;
        if (userInfo != null) {
            userInfo.putIfAbsent("name", "");
            userInfo.putIfAbsent("major", "");
            userInfo.putIfAbsent("class", "");
            userInfo.putIfAbsent("university", "");
            userInfo.putIfAbsent("academy", "");
            userInfo.putIfAbsent("avatar", "");
            userInfo.putIfAbsent("sex", "");
            userInfo.putIfAbsent("age", 0);
            userInfo.putIfAbsent("address", "");
            userInfo.putIfAbsent("phone", "");
            userInfo.putIfAbsent("email", "");
            userInfo.putIfAbsent("bindId", 0);
            Rewards rewards = iRewardService.selectReward(uid);
            if (rewards == null) {
                userInfo.put("reward_points", 0);
            } else {
                userInfo.put("reward_points", rewards.getReward_points());
            }
            responseModel = new ResponseModel(200, userInfo);
        } else {
            responseModel = new ResponseModel(199, "该用户不存在");
        }
        return responseModel;
    }

    @RequestMapping(value = "/selectList", method = RequestMethod.GET)
    public void selectList(HttpServletResponse resp, @RequestParam(value = "name", required = false,defaultValue = "") String name,
                           @RequestParam(value = "university", required = false,defaultValue = "") String university,
                           @RequestParam(value = "academy", required = false,defaultValue = "") String academy,
                           @RequestParam(value = "pageNum", required = false, defaultValue = "1") int pageNum,
                           @RequestParam(value = "pageSize", required = false, defaultValue = "10") int pageSize) {
        try {
            if(name.contains(" ")||name.contains("'")||name.contains("\"")
                    ||university.contains(" ")||university.contains("'")||university.contains("\"")
                    ||academy.contains(" ")||academy.contains("'")||academy.contains("\"")){
                return;
            }
            List<Map<String, Object>> userlist = iUserInfoService.selectList(name, university, academy);
            for (Map<String, Object> map : userlist) {
                map.putIfAbsent("name", "");
                map.putIfAbsent("university", "");
                map.putIfAbsent("academy", "");
                map.putIfAbsent("avatar", "");
                map.putIfAbsent("sex", "");
                map.putIfAbsent("age", 0);
                map.putIfAbsent("address", "");
                map.putIfAbsent("phone", "");
                map.putIfAbsent("email", "");
            }
            try {
                JSONObject data1 = PageUtil.wrap2(userlist,"User",pageSize,pageNum);
                resp.setCharacterEncoding("utf-8");
                /*得到输出流*/
                PrintWriter respWritter = resp.getWriter();
                /*将JSON格式的对象toString()后发送*/
                respWritter.append(data1.toString());
            } catch (Exception e) {
                e.printStackTrace();
                logger.error(String.valueOf(e));
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(String.valueOf(e));
        }
    }


    @RequestMapping(value = "/facesComparison", method = RequestMethod.POST)
    @CurrentLimiter(QPS = 5)
    public ResponseModel facesComparison(@RequestParam("lid") String lid, @RequestParam("cid") String cid,@RequestParam("file") MultipartFile multipartFile) {
        ArcSoftFace arcSoftFace = new ArcSoftFace();
        try {
            File file = new File(TEMPORARY_FILE_PATH2+GetInfoUtil.getFileName());
            multipartFile.transferTo(file);
            List<Map<String, Object>> targetFaceFeatureList = new ArrayList<>();
            List<Map<String, Object>> sourceFaceFeatureList = iUserInfoService.selectFaceFeatures(cid);
            if (sourceFaceFeatureList.isEmpty()) {
                return new ResponseModel(185, "名单中没有人脸信息，请检查名单或名单id是否正确");
            }
            List<FaceInfo> faceInfoList = arcSoftFace.detectFaces(file);
            List<byte[]> bytesList = arcSoftFace.extractFaceFeatures(file, faceInfoList);
            for (byte[] aBytesList : bytesList) {
                Map<String, Object> map = new HashMap<>(1);
                map.put("faceFeature", aBytesList);
                targetFaceFeatureList.add(map);
            }
            if (bytesList.isEmpty()) {
                arcSoftFace.destroyEngine();
                return new ResponseModel(186, "上传的图片没有识别到人脸信息");
            }
            List<String> result = arcSoftFace.compareFaceFeatures(targetFaceFeatureList, sourceFaceFeatureList, 0.75);
            List<String> resultPeople = new ArrayList<>();
            int errorCode;
            for (int i = 0; i < result.size(); i++) {
                errorCode = addRewards(lid, i, result);
                if (-1 == errorCode) {
                    arcSoftFace.destroyEngine();
                    return new ResponseModel(106, "签到已过期！");
                }
                resultPeople.add(result.get(i));
            }
            arcSoftFace.destroyEngine();
            return new ResponseModel(200, "新增多人签到成功", resultPeople);
        } catch (Exception e) {
            logger.error(String.valueOf(e));
            arcSoftFace.destroyEngine();
            return new ResponseModel(187, "新增失败", 0);
        }
    }

    @RequestMapping(value = "/videoFacesComparison", method = RequestMethod.POST)
    @CurrentLimiter(QPS = 5)
    public ResponseModel videoFacesComparison(@RequestParam("lid")String lid, @RequestParam("cid") String cid,@RequestParam("file") MultipartFile multipartFile) {
        ArcSoftFace arcSoftFace = new ArcSoftFace();
        try {
            List<Map<String, String>> tempList = iUserInfoService.selectTempList(lid);
            File file = new File(TEMPORARY_FILE_PATH2+GetInfoUtil.getFileName());
            multipartFile.transferTo(file);
            List<Map<String, Object>> targetFaceFeatureList = new ArrayList<>();
            List<Map<String, Object>> sourceFaceFeatureList = iUserInfoService.selectFaceFeatures(cid);
            if (sourceFaceFeatureList.isEmpty()) {
                return new ResponseModel(185, "名单中没有人脸信息，请检查名单或名单id是否正确");
            }
            List<FaceInfo> faceInfoList = arcSoftFace.detectFaces(file);
            for (int i = sourceFaceFeatureList.size() - 1; i >= 0; i--) {
                for (Map<String, String> aTempList : tempList) {
                    if (sourceFaceFeatureList.get(i).get("uid").equals(aTempList.get("uid"))) {
                        sourceFaceFeatureList.remove(i);
                        break;
                    }
                }
            }
            List<byte[]> bytesList = arcSoftFace.extractFaceFeatures(file, faceInfoList);
            for (byte[] aBytesList : bytesList) {
                Map<String, Object> map = new HashMap<>(1);
                map.put("faceFeature", aBytesList);
                targetFaceFeatureList.add(map);
            }
            if (bytesList.isEmpty()) {
                arcSoftFace.destroyEngine();
                return new ResponseModel(186, "上传的图片没有识别到人脸信息");
            }
            List<String> result = arcSoftFace.compareFaceFeatures(targetFaceFeatureList, sourceFaceFeatureList, 0.75);
            List<Map<String, Object>> resultPeople = new ArrayList<>();
            int errorCode;
            for (int i = 0; i < result.size(); i++) {
                errorCode = addRewards(lid, i, result);
                if (errorCode == -1) {
                    arcSoftFace.destroyEngine();
                    return new ResponseModel(106, "签到已过期");
                }
                iUserInfoService.addTempList(lid, result.get(i));
                Map<String, Object> map = iUserInfoService.selectUser(result.get(i));
                resultPeople.add(map);
            }
            arcSoftFace.destroyEngine();
            return new ResponseModel(200, "新增多人签到成功", resultPeople);
        } catch (Exception e) {
            logger.error(String.valueOf(e));
            arcSoftFace.destroyEngine();
            return new ResponseModel(187, "新增失败", 0);
        }
    }

    @RequestMapping(value = "/clearCache", method = RequestMethod.GET)
    public ResponseModel clearCache(@RequestParam("lid") String lid) {
        iUserInfoService.deleteTempList(lid);
        return new ResponseModel(200, "清除成功");
    }

    @RequestMapping(value = "/checkFaceExist", method = RequestMethod.GET)
    @CurrentLimiter(QPS = 5)
    public ResponseModel checkFaceExist(@RequestParam("uid") String uid) {
        String id = iUserInfoService.selectFaceInfo(uid);
        if (id == null) {
            return new ResponseModel(200, "未注册人脸", 0);
        }
        return new ResponseModel(200, "已注册人脸", 1);
    }

    @RequestMapping(value = "/loginWeb", method = RequestMethod.POST)
    @CurrentLimiter(QPS = 5)
    public ResponseModel loginWeb(HttpServletRequest request,@RequestBody JSONObject data) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            String uid1 = data.get("uid1").toString();
            //账号可用判断
            User user=redisService.findByUId(uid1);
            int count;
            if(user!=null){
                String nextLogin=user.getNextLogin();
                if(nextLogin!=null&& (!"".equals(nextLogin))){
                    Date date=new Date(System.currentTimeMillis());
                    ChangeDate changeDate=new ChangeDate();
                    changeDate.setSettime(nextLogin);
                    if(!date.after(changeDate.settime)){
                        return new ResponseModel(170, "账号已冻结,请于"+nextLogin+"之后登陆");
                    }else {
                        redisService.updateLogin(uid1,"0","");
                    }
                }
            }

            String password;
            try {
                password = data.get("password").toString();
            } catch (Exception e) {
                password = "";
            }
            UserInfo userInfo = iUserInfoService.selectByUid1(uid1);
            String pwd = userInfo.getPassword();
            if (pwd != null) {

                String salt=userInfo.getSalt();
                if(salt == null){
                    return new ResponseModel(199,"请先重置密码");
                }
                String[] strs=EncryptionUtil.md5Encrypt(salt,password);

                String ip=GetInfoUtil.getIpAddr(request);
                if (pwd.equals(strs[1])) {
                    //保存登陆信息
                    String currentTime = dateFormat.format(System.currentTimeMillis());
                    if(user==null){
                        redisService.addUser(uid1,ip,currentTime,"0");
                    }else {
                        redisService.updateByUId(uid1,ip,currentTime);
                    }
                    logger.info("uid:"+uid1+",ip:"+ip);

                    return new ResponseModel(200, "登录成功", userInfo);
                } else {
                    //保存登陆失败的状态
                    Date date=new Date(System.currentTimeMillis());
                    String currentTime = dateFormat.format(date);

                    if(user==null){
                        redisService.addUser(uid1,ip,currentTime,"0");
                        count=1;
                    }else {
                        count=Integer.parseInt(user.getErrorCounts())+1;
                    }
                    String nextLogin="";
                    if(count==3){
                        //创建Calendar实例
                        Calendar cal = Calendar.getInstance();
                        //设置当前时间
                        cal.setTime(date);
                        //在当前时间基础上加一月
                        cal.add(Calendar.MONTH,1);
                        nextLogin=dateFormat.format(cal.getTime());
                        redisService.updateLogin(uid1,count+"",nextLogin);
                    }else {
                        redisService.updateLogin(uid1,count+"","");
                    }
                    logger.error("登陆错误 uid:"+uid1+",ip:"+ip+",nextLogin:"+nextLogin);

                    return new ResponseModel(199, "密码错误");
                }
            } else {
                return new ResponseModel(198, "请先重置密码");
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(String.valueOf(e));
            return new ResponseModel(197, "不存在此用户");
        }
    }

    @RequestMapping(value = "/resetPwd", method = RequestMethod.POST)
    @CurrentLimiter(QPS = 5)
    public ResponseModel resetPwd(@RequestBody JSONObject data) {
        try {
            String uid1 = data.get("uid1").toString();
            String password;
            try {
                password = data.get("password").toString();
            } catch (Exception e) {
                return new ResponseModel(196, "请输入新密码");
            }
            String[] strs=EncryptionUtil.md5Encrypt("",password);
            iUserInfoService.updatePassword(uid1, strs[1],strs[0]);
            return new ResponseModel(200, "重置成功");
        } catch (Exception e) {
            return new ResponseModel(197, "不存在此用户");
        }
    }

    @RequestMapping(value = "/rewardPoints", method = RequestMethod.GET)
    @CurrentLimiter(QPS = 5)
    public ResponseModel rewardPoints(@RequestParam("uid") String uid) {
        try {
            int rewardPoints = iRewardService.selectReward(uid).getReward_points();
            return new ResponseModel(200, "获取成功", rewardPoints);
        } catch (Exception e) {
            return new ResponseModel(153, "获取失败");
        }
    }

    @RequestMapping(value = "/findExamineState", method = RequestMethod.GET)
    public ResponseModel findExamineState(@RequestParam("uid") String uid) {
        try {
            return new ResponseModel(200, "获取成功", iUserInfoService.selectExamine(uid));
        } catch (Exception e) {
            logger.error(String.valueOf(e));
            return new ResponseModel(153, "获取失败");
        }
    }


    @RequestMapping(value = "/requestForAccess",method = RequestMethod.GET)
    public  ResponseModel requestForAccess(@RequestParam("uid")String uid,@RequestParam("roleId")int roleId){
        iUserInfoService.updateIsExamine(uid,1);
        iUserInfoService.updateRoleId1(uid,roleId);
        return new ResponseModel(200,"已提交申请");
    }

    @RequestMapping(value = "/bindId",method = RequestMethod.GET)
    public  ResponseModel bindId(@RequestParam("uid")String uid,@RequestParam("bindId")int bindId){
        iUserInfoService.updateBindId(uid, bindId);
        redisService.updateBindid(uid,bindId+"");
        return new ResponseModel(200,"绑定成功");
    }

    @RequestMapping(value = "/applicationApproval",method = RequestMethod.GET)
    public  ResponseModel applicationApproval(@RequestParam("uid")String uid){
        iUserInfoService.updateIsExamine(uid,2);
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String currentDay = dateformat.format(System.currentTimeMillis());
        iUserInfoService.insertResult(
                uid,
                "已通过",
                "",
                currentDay);
        return new ResponseModel(200,"修改成功");
    }

    @RequestMapping(value = "/selectUnExamine",method = RequestMethod.GET)
    public ResponseModel selectUnExamine(){
        return new ResponseModel(200,"查询成功",iUserInfoService.selectUnExamine());
    }

    private int addRewards(String lid, int i, List<String> result) {
        SignInActivity signInActivity = iSignInActivityService.selectAct(lid);
        String cid = signInActivity.getCid();
        String tid = iClassesService.selectTidByCid(cid);
        Rewards rewards = iRewardService.selectReward(result.get(i));
        Rewards rewardsTeacher = iRewardService.selectReward(tid);
        UserClass userClass = iUserClassService.selectUserClass(result.get(i), cid);
        if (userClass != null) {
            SignInRecord signInRecord = iSignInRecordService.selectRecExist(result.get(i), lid);
            if (signInRecord == null) {
                SignInLink signInLink = iSignInActivityService.selectLinkByLid(lid);
                ChangeDate changeDate = new ChangeDate();
                changeDate.setSettime(signInLink.getEndTime());
                Date date = new Date(System.currentTimeMillis());
                if (date.before(changeDate.settime)) {
                    String id = GetInfoUtil.getId();
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String createTime = dateFormat.format(System.currentTimeMillis());
                    iSignInRecordService.addNewRecord(id, lid, result.get(i), createTime,"normal");
                    String currentDay = dateFormat.format(System.currentTimeMillis()).substring(0, 10);
                    String lastGainDay;
                    int a = rewardsTeacher.getLimit_from_record_a();
                    int b = rewardsTeacher.getLimit_from_record_b();
                    int c = rewardsTeacher.getLimit_from_record_c();
                    int activity = rewardsTeacher.getLimit_from_activity();
                    //学生签到成功，教师加2分
                    int dayMaxRewards = 100;
                    if (rewardsTeacher.getDay_reward() < dayMaxRewards) {
                        int rewardPerTimeForTea = 2;
                        iRewardService.updateRewards(tid, a, b, c, activity, currentDay,
                                rewardsTeacher.getReward_points() + rewardPerTimeForTea,
                                rewardsTeacher.getDay_reward() + rewardPerTimeForTea
                        );
                    }
                    //有则更新记录
                    int rewardPerTime = 30;
                    if (rewards != null) {
                        int limitFromRecordActivity = rewards.getLimit_from_activity();
                        lastGainDay = rewards.getLast_gain_day();
                        int rewardPoint = rewards.getReward_points();
                        if (!lastGainDay.equals(currentDay)) {
                            //如果上次获取积分的日期不等于今天，则直接加上积分，并将上次获取积分的日期改为今天
                            iRewardService.updateRewards(result.get(i), 1, 0, 0,
                                    0, currentDay, rewardPoint + rewardPerTime, rewardPerTime);
                            return 0;
                        }
                        //如果今日获取积分已达上限
                        if (dayMaxRewards < rewards.getDay_reward()) {
                            return 0;
                        }
                        //判断是不是今天第一次获取
                        else if (rewards.getLimit_from_record_a() == 0) {
                            iRewardService.updateRewards(
                                    result.get(i), 1, 0, 0, limitFromRecordActivity, currentDay,
                                    rewardPoint + rewardPerTime, rewards.getDay_reward() + rewardPerTime);
                        }
                        //判断是不是今天第二次获取
                        else if (rewards.getLimit_from_record_b() == 0) {
                            iRewardService.updateRewards(
                                    result.get(i), 1, 1, 0, limitFromRecordActivity, currentDay,
                                    rewardPoint + rewardPerTime, rewards.getDay_reward() + rewardPerTime);
                        }
                        //判断是不是今天第三次获取
                        else if (rewards.getLimit_from_record_c() == 0) {
                            iRewardService.updateRewards(
                                    result.get(i), 1, 1, 1, limitFromRecordActivity, currentDay,
                                    rewardPoint + rewardPerTime, rewards.getDay_reward() + rewardPerTime
                            );
                        }
                        return 0;
                    }
                    //无记录新增积分记录
                    iRewardService.addNewRewards(result.get(i), 1, 0, 0, 0,
                            currentDay, rewardPerTime, rewardPerTime
                    );
                    return 0;
                }
                return -1;
            }
            return 0;
        }
        return 0;
    }

    @RequestMapping(value = "/selectBindid", method = RequestMethod.GET)
    public ResponseModel selectBindid(@RequestParam("bindid") int bindid) {
        UserInfo userInfo=iUserInfoService.selectByBindid(bindid);
        if(userInfo!=null){
            return new ResponseModel(200, "查询成功",userInfo);
        }else {
            return new ResponseModel(199, "查无此人");
        }
    }

    @RequestMapping(value = "/updateRole", method = RequestMethod.GET)
    public ResponseModel updateRole(HttpServletRequest request,@RequestParam("bindid") int bindid,@RequestParam("roleid")int roleid) {
        try {
            String authorization = request.getHeader("Authorization");
            String token = null;
            if(authorization != null) {
                token = authorization.substring(7);
            }
            if(token==null){
                return new ResponseModel(199, "token获取失败");
            }
            if(!"administrator".equals(JWT.decode(token).getClaim("uid").asString())){
                return new ResponseModel(199, "无权访问");
            }
            iUserInfoService.updateRoleId(bindid,roleid);
            return new ResponseModel(200, "身份更改成功");
        }catch (Exception e){
            return new ResponseModel(199, "身份更改失败");
        }
    }

    @RequestMapping(value = "/refuseApply", method = RequestMethod.POST)
    public ResponseModel refuseApply(HttpServletRequest request,@RequestBody JSONObject jsonObject) {
        try {
            String authorization = request.getHeader("Authorization");
            String token = null;
            if(authorization != null) {
                token = authorization.substring(7);
            }
            if(token==null){
                return new ResponseModel(199, "token获取失败");
            }
            if(!"administrator".equals(JWT.decode(token).getClaim("uid").asString())){
                return new ResponseModel(199, "无权访问");
            }
            SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String currentDay = dateformat.format(System.currentTimeMillis());
            iUserInfoService.insertResult(
                    jsonObject.getString("uid"),
                    "未通过",
                    jsonObject.getString("reason"),
                    currentDay);
            iUserInfoService.updateIsExamine(
                    jsonObject.getString("uid"),0);
            return new ResponseModel(200, "操作成功");
        }catch (Exception e){
            logger.error(String.valueOf(e));
            return new ResponseModel(199, "操作失败");
        }
    }

    @RequestMapping(value = "/selectResult", method = RequestMethod.GET)
    public ResponseModel selectResult(HttpServletRequest request,@RequestParam("uid") String uid) {
        try {
            String authorization = request.getHeader("Authorization");
            String token = null;
            if(authorization != null) {
                token = authorization.substring(7);
            }
            if(token==null){
                return new ResponseModel(199, "token获取失败");
            }
            if(!"administrator".equals(JWT.decode(token).getClaim("uid").asString())){
                return new ResponseModel(199, "无权访问");
            }
            int count = 0;
            List<Map<String, Object>> mapList = iUserInfoService.selectResultList(uid);
            for (Map<String, Object> map : mapList) {
                if("0".equals(map.get("isread").toString())){
                    count++;
                }
            }
            Map<String, Object> map = new HashMap<>(2);
            map.put("count",count);
            map.put("list",mapList);
            return new ResponseModel(200, "获取成功",map);
        }catch (Exception e){
            logger.error(String.valueOf(e));
            return new ResponseModel(199, "获取失败");
        }
    }

    @RequestMapping(value = "/updateIsRead", method = RequestMethod.GET)
    public ResponseModel updateIsRead(HttpServletRequest request,@RequestParam("uid")String uid,@RequestParam("id")int id) {
        try {
            String authorization = request.getHeader("Authorization");
            String token = null;
            if(authorization != null) {
                token = authorization.substring(7);
            }
            if(token==null){
                return new ResponseModel(199, "token获取失败");
            }
            if(!"administrator".equals(JWT.decode(token).getClaim("uid").asString())){
                return new ResponseModel(199, "无权访问");
            }
            iUserInfoService.updateIsRead(uid, id);
            return new ResponseModel(200, "");
        }catch (Exception e){
            return new ResponseModel(199, "");
        }
    }

    @RequestMapping(value = "/getLoginCode", method = RequestMethod.GET)
    public ResponseModel getLoginCode() {
        return iScanCodeLoginService.getLoginCode();
    }

    @RequestMapping(value = "/scanCodeLogin", method = RequestMethod.GET)
    public ResponseModel scanCodeLogin(
            @RequestParam("uid")String uid,
            @RequestParam("sessionId")String sessionId,
            @RequestParam(value = "lid",required = false,defaultValue = "commonLogin")String lid,
            @RequestParam(value = "state",required = false,defaultValue = "commonLogin")String state,
            @RequestParam(value = "endTime",required = false,defaultValue = "commonLogin")String endTime,
            @RequestParam(value = "actId",required = false,defaultValue = "commonLogin")String actId,
            @RequestParam(value = "title",required = false,defaultValue = "commonLogin")String title,
            @RequestParam(value = "linkType",required = false,defaultValue = "commonLogin")String linkType,
            @RequestParam(value = "className",required = false,defaultValue = "commonLogin")String className,
            @RequestParam(value = "cid",required = false,defaultValue = "commonLogin")String cid,
            @RequestParam(value = "type",required = false,defaultValue = "commonLogin")String type

    ) {
        return iScanCodeLoginService.scanCodeLogin(sessionId, uid,lid,state,endTime,actId,title,linkType,className,cid,type);
    }

    @RequestMapping(value = "/waitConfirmation", method = RequestMethod.GET)
    public ResponseModel waitConfirmation(
            @RequestParam("uid")String uid,
            @RequestParam("sessionId")String sessionId,
            @RequestParam(value = "type",required = false,defaultValue = "commonLogin")String type
    ) {
        return iScanCodeLoginService.waitConfirmation(sessionId, uid, type);
    }

    @RequestMapping(value = "/canUpdateFace", method = RequestMethod.GET)
    public ResponseModel canUpdateFace(@RequestParam("uid")String uid) {
        return iUserInfoService.selectCreateTime(uid);
    }

    @RequestMapping(value = "/sendMail", method = RequestMethod.POST)
    public ResponseModel sendMail(@RequestParam("subject") String subject, @RequestParam("content") String content, @RequestParam("image") MultipartFile image) {
        return iUserInfoService.sendMail(subject, content, image);
    }
}

